package wowmobile;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class MonsterFight {

    private List<Player> playerList;
    private List<Monster> enemyList;
    private Comparator<Order> c = new OrderComp();
    private PriorityQueue<Order> orderQueue = new PriorityQueue<Order>(1, c);

    public MonsterFight(List<Player> playerList, List<Monster> monsterList) {
        this.playerList = playerList;
        this.enemyList = monsterList;
        List<Integer> playerIDlist = new ArrayList<Integer>();
        for (int i = 0; i < playerList.size(); i++) {
            playerIDlist.add(playerList.get(i).getStats().getId());
            playerList.get(i).getStats().setDefending(true);
        }
        for (int i = 0; i < enemyList.size(); i++) {
            enemyList.get(i).setThreat(new Threat(playerIDlist));
        }
        System.out.println(playerList.size());
    }

    public List<Monster> getEnemyList() {
        return enemyList;
    }

    public List<Player> getPlayerList() {
        return playerList;
    }

    public PriorityQueue<Order> getOrderQueue() {
        return orderQueue;
    }

    //co turę regenerujemy 10% many
    public void orderTurns() {
        Order order;
        for (int i = 0; i < enemyList.size(); i++) {
            order = new Order(enemyList.get(i));
            //order.getMonster().changeMana(-(int) (order.getMonster().getMaxmana() * 0.1));
            this.orderQueue.add(order);
        }
        for (int i = 0; i < playerList.size(); i++) {
            order = new Order(playerList.get(i));
            //order.getPlayer().getStats().changeMana(-(int) (order.getPlayer().getStats().getMaxmana() * 0.1));
            this.orderQueue.add(order);
        }
    }

    //ally/enemy+","+ally/enemy+","+command[0]+","+command[1]+","+command[2]+","+command[3]+","+nazwa czaru/przedmiotu+","+zmiana many postaci+","+zmiana:hp+","+mana+","+defence+","+attack+","+speed
    private String PlayerAction(String[] command, Player player, int target, int actiontype, int action) {
        String info = "";
        switch (actiontype) {
            //z broni
            case 0: {
                if (command[1].equals("7")) {
                    //info = "enemy" + "," + command[0] + "," + command[1] + "," + command[2] + "," + 0 + "," + "fail" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                    info = "ally" + "," + command[0] + "," + 0 + "," + 0 + "," + 0 + "," + "defending" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                    player.getStats().setDefending(true);
                } else {
                    Monster monster = enemyList.get(target);
                    int monsterhp = monster.getHp();
                    monster.changeHP(player.getStats().getAttack() + player.getStats().getSpeed(), player.getStats().getLevel());
                    int damage = monsterhp - monster.getHp();

                    enemyList.get(target).getThreat().raiseThreat(player.getStats().getId(), damage * player.getStats().getPclass().getThreat());
                    info = "enemy" + "," + command[0] + "," + command[1] + "," + command[2] + "," + command[3] + "," + "attacking" + "," + 0 + "," + (monsterhp - monster.getHp()) + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                }
                break;
            }
            //magia
            case 1: {
                //wyjątek od komunikatu!! po ally jest kolejne ally/enemy
                if (command[1].equals("7")) {
                    if (!player.getStats().getMagiclist().get(action).isEnemytarget()) {
                        if (player.getStats().getMana() >= playerList.size() * player.getStats().getMagiclist().get(action).getManacost()) {
                            Player targetedplayer = playerList.get(0);
                            for (int i = 0; i < playerList.size(); i++) {
                                targetedplayer = playerList.get(i);
                                targetedplayer.getStats().statChange(player.getStats().getMagiclist().get(action).getHp(), player.getStats().getMagiclist().get(action).getMana(), player.getStats().getMagiclist().get(action).getDefence(), player.getStats().getMagiclist().get(action).getAttack(), player.getStats().getMagiclist().get(action).getSpeed(), player.getStats().getLevel());
                                player.getStats().changeMana(player.getStats().getMagiclist().get(action).getManacost());
                                if (targetedplayer.getStats().getHp() > 0) {
                                    for (int j = 0; j < enemyList.size(); j++) {
                                        enemyList.get(j).getThreat().ressurected(targetedplayer.getStats().getId());
                                        enemyList.get(target).getThreat().raiseThreat(player.getStats().getId(), (player.getStats().getMagiclist().get(action).getHp() + 1) * player.getStats().getPclass().getThreat());
                                    }
                                }
                            }
                            info = "ally" + "," + command[0] + "," + command[1] + "," + command[2] + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getImage() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getName() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getManacost() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getHp() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getMana() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getDefence() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getAttack() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getSpeed();
                        } else {
                            //info = "ally" + "," + command[0] + "," + command[1] + "," + command[2] + "," + 0 + "," + "fail" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                            info = "ally" + "," + command[0] + "," + 0 + "," + 0 + "," + 0 + "," + "defending" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                            player.getStats().setDefending(true);
                        }
                    } else {
                        if (player.getStats().getMana() >= enemyList.size() * player.getStats().getMagiclist().get(action).getManacost()) {
                            Monster targetedenemy = enemyList.get(0);
                            for (int i = 0; i < enemyList.size(); i++) {
                                targetedenemy = enemyList.get(i);
                                targetedenemy.statChange(player.getStats().getMagiclist().get(action).getHp(), player.getStats().getMagiclist().get(action).getMana(), player.getStats().getMagiclist().get(action).getDefence(), player.getStats().getMagiclist().get(action).getAttack(), player.getStats().getMagiclist().get(action).getSpeed(), player.getStats().getLevel());
                                player.getStats().changeMana(player.getStats().getMagiclist().get(action).getManacost());
                                for (int j = 0; j < enemyList.size(); j++) {
                                    enemyList.get(j).getThreat().raiseThreat(player.getStats().getId(), player.getStats().getPclass().getThreat());
                                    enemyList.get(target).getThreat().raiseThreat(player.getStats().getId(), (player.getStats().getMagiclist().get(action).getHp() + 1) * player.getStats().getPclass().getThreat());
                                }
                            }
                            info = "enemy" + "," + command[0] + "," + command[1] + "," + command[2] + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getImage() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getName() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getManacost() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getHp() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getMana() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getDefence() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getAttack() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getSpeed()+Parser.parseEnemiesHp(enemyList);
                        } else {
                            //info = "enemy" + "," + command[0] + "," + command[1] + "," + command[2] + "," + 0 + "," + "fail" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                            info = "ally" + "," + command[0] + "," + 0 + "," + 0 + "," + 0 + "," + "defending" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                            player.getStats().setDefending(true);
                        }
                    }
                } else {
                    if (player.getStats().getMana() >= player.getStats().getMagiclist().get(action).getManacost()) {
                        if (!player.getStats().getMagiclist().get(action).isEnemytarget()) {
                            Player targetedplayer = playerList.get(target);
                            targetedplayer.getStats().statChange(player.getStats().getMagiclist().get(action).getHp(), player.getStats().getMagiclist().get(action).getMana(), player.getStats().getMagiclist().get(action).getDefence(), player.getStats().getMagiclist().get(action).getAttack(), player.getStats().getMagiclist().get(action).getSpeed(), player.getStats().getLevel());
                            player.getStats().changeMana(player.getStats().getMagiclist().get(action).getManacost());

                            if (targetedplayer.getStats().getHp() > 0) {
                                for (int j = 0; j < enemyList.size(); j++) {
                                    enemyList.get(j).getThreat().ressurected(targetedplayer.getStats().getId());
                                    enemyList.get(target).getThreat().raiseThreat(player.getStats().getId(), (player.getStats().getMagiclist().get(action).getHp() + 1) * player.getStats().getPclass().getThreat());
                                }
                            }

                            info = "ally" + "," + command[0] + "," + command[1] + "," + command[2] + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getImage() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getName() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getManacost() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getHp() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getMana() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getDefence() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getAttack() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getSpeed();
                        } else {
                            Monster targetedenemy = enemyList.get(target);
                            int hp = targetedenemy.getHp();
                            targetedenemy.statChange(player.getStats().getMagiclist().get(action).getHp(), player.getStats().getMagiclist().get(action).getMana(), player.getStats().getMagiclist().get(action).getDefence(), player.getStats().getMagiclist().get(action).getAttack(), player.getStats().getMagiclist().get(action).getSpeed(), player.getStats().getLevel());
                            player.getStats().changeMana(player.getStats().getMagiclist().get(action).getManacost());
                            int damage = targetedenemy.getHp() - hp;

                            enemyList.get(target).getThreat().raiseThreat(player.getStats().getId(), (player.getStats().getMagiclist().get(action).getHp() + 1) * player.getStats().getPclass().getThreat());

                            info = "enemy" + "," + command[0] + "," + command[1] + "," + command[2] + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getImage() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getName() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getManacost() + "," + damage + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getMana() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getDefence() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getAttack() + "," + player.getStats().getMagiclist().get(Integer.valueOf(command[3])).getSpeed();
                        }
                    } else {
                        //info = "ally" + "," + command[0] + "," + command[1] + "," + command[2] + "," + 0 + "," + "fail" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                        info = "ally" + "," + command[0] + "," + 0 + "," + 0 + "," + 0 + "," + "defending" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                        player.getStats().setDefending(true);
                    }
                }
                break;
            }
            //item, są tylko dla playerów, 1 player = 1 item
            case 2: {
                if (target == 7) {
                    info = "ally" + "," + command[0] + "," + 0 + "," + 0 + "," + 0 + "," + "defending" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
                    player.getStats().setDefending(true);
                } else {
                    Player targetedplayer = playerList.get(target);
                    String name = player.getStats().getHanditems().get(target).getName();
                    targetedplayer.getStats().statChange(player.getStats().getHanditems().get(Integer.valueOf(command[3])).getHp(), player.getStats().getHanditems().get(Integer.valueOf(command[3])).getMana(), player.getStats().getHanditems().get(Integer.valueOf(command[3])).getDefence(), player.getStats().getHanditems().get(Integer.valueOf(command[3])).getAttack(), player.getStats().getHanditems().get(Integer.valueOf(command[3])).getSpeed(), player.getStats().getLevel());
                    player.getStats().useHandItem(action);

                    info = "ally" + "," + command[0] + "," + command[1] + "," + command[2] + "," + command[3] + "," + player.getStats().getHanditems().get(Integer.valueOf(command[3])).getName() + "," + 0 + "," + player.getStats().getHanditems().get(Integer.valueOf(command[3])).getHp() + "," + player.getStats().getHanditems().get(Integer.valueOf(command[3])).getMana() + "," + player.getStats().getHanditems().get(Integer.valueOf(command[3])).getDefence() + "," + player.getStats().getHanditems().get(Integer.valueOf(command[3])).getAttack() + "," + player.getStats().getHanditems().get(Integer.valueOf(command[3])).getSpeed();
                }
                break;
            }
        }
        return info;
    }

    //chyba player turn powinno coś zwrócić do czegoś, co roześle graczom dane dotyczące rundy
    //pamiętać, żeby po wskrzeszeniu gracza ustawić alive w threat wszystkim monsterów
    //koniecznie sprawdzać, czy gracz żyje!
    public String playerTurn(Player player, String action) {
        //actiontype np magia/item np 0 = atak z broni
        //action id z listy magii/itemów np jak actiontype = 0, to nie ma wartości
        //target id z listy monsterów/graczy
        //co zrobił gracz
        //action: "bywho towho actiontype action"
        String command[] = action.split(",");
        String info = "";
        player.getStats().setDefending(false);
        int switcher = Integer.valueOf(command[1]);
        if (switcher == 0) {
            player.getStats().setDefending(true);
            info = "ally" + "," + command[0] + "," + 0 + "," + 0 + "," + 0 + "," + "defending" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
        } else {
            try {
                info = PlayerAction(command, player, Integer.valueOf(command[1]) - 1, Integer.valueOf(command[2]), Integer.valueOf(command[3]));
            } catch (IndexOutOfBoundsException e) {
                player.getStats().setDefending(true);
                info = "ally" + "," + command[0] + "," + 0 + "," + 0 + "," + 0 + "," + "defending" + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0 + "," + 0;
            }
        }

        return "ally" + "," + info;
    }
    //chyba ai powinno coś zwrócić do czegoś, co roześle graczom dane dotyczące rundy
    //pamiętać, żeby po śmierci gracza ustawić died w threat wszystkim monsterów

    //ally/enemy+","+ally/enemy+","+command[0]+","+command[1]+","+command[2]+","+command[3]+","+nazwa czaru/przedmiotu+","+zmiana many postaci+","+zmiana:hp+","+mana+","+defence+","+attack+","+speed
    public String aiTurn(Monster monster) {
        //co robi ai
        int playerid = monster.getThreat().nextAttack();
        Player player = playerList.get(0);
        for (int i = 0; i < playerList.size(); i++) {
            if (playerList.get(i).getStats().getId() == playerid) {
                player = playerList.get(i);
            }
        }
        int playerhp = player.getStats().getHp();
        if (player.getStats().isDefending()) {
            player.getStats().changeHP((monster.getAttack() + monster.getSpeed()) / 2, monster.getLevel());
        } else {
            player.getStats().changeHP(monster.getAttack() + monster.getSpeed(), monster.getLevel());
        }
        if (player.getStats().getHp() == 0) {
            player.getStats().setDefending(false);
            for (int i = 0; i < enemyList.size(); i++) {
                enemyList.get(i).getThreat().died(playerid);
            }
        }

        return "enemy" + "," + "ally" + "," + Integer.toString(enemyList.indexOf(monster) + 1) + "," + Integer.toString(playerList.indexOf(player) + 1) + "," + 0 + "," + 0 + "," + "null" + "," + 0 + "," + Integer.toString(playerhp - player.getStats().getHp()) + "," + 0 + "," + 0 + "," + 0 + "," + 0;
    }

    public int allDied() {
        int counter = 0;
        for (int i = 0; i < enemyList.size(); i++) {
            if (enemyList.get(i).getHp() == 0) {
                counter = counter + 1;
            }
        }
        if (counter == enemyList.size()) {
            return 1;
        } else {
            counter = 0;
            for (int i = 0; i < playerList.size(); i++) {
                if (playerList.get(i).getStats().getHp() == 0) {
                    counter = counter + 1;
                }
            }
            if (counter == playerList.size()) {
                return 2;
            } else {
                return 0;
            }
        }
    }
}
